<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2021/08/05
 * Time: 14:29
 * @link http://www.lmterp.cn
 */

namespace app\admin\controller\report;

use app\admin\controller\BaseController;
use app\common\model\ProductStore;
use app\common\model\ReportOrderDay;

/**
 * 走势图
 * Class TrendController
 * @package app\admin\controller\report
 */
class TrendController extends BaseController
{

    /**
     * 年走势图
     * @var string
     */
    private $year;

    /**
     * 月走势图
     * @var string
     */
    private $month;

    /**
     * 首页
     * @date 2021/08/05
     * @author longli
     */
    public function index()
    {
        if($this->request->isAjax())
        {
            $this->year = $this->request->request("year", date('Y'), 'trim');
            $this->month = $this->request->request("month", '', 'trim');
            if(!empty($this->month) && $this->month < 10) $this->month = "0{$this->month}";
            $type = $this->request->request('type');
            $type .= !empty($this->year) && !empty($this->month) ? 'Month' : 'Year';
            if(method_exists($this, $type)) $this->$type();
            return;
        }
        $this->assign('year', \app\common\library\Tools::getRecentYear(10));
        $this->assign('month', range(1, 12));
        return $this->fetch('order');
    }

    /**
     * 销量年走势图
     * @date 2021/08/05
     * @author longli
     */
    private function orderYear()
    {
        $skus = $this->getSkus();
        if(empty($skus)) $this->error("暂无数据");
        $yearData = ReportOrderDay::field(["SUM(qty) total_qty", "SUM(total_price) total_price", "ref_value", "DATE_FORMAT(stat_date, '%Y-%m') stat_month", "DATE_FORMAT(stat_date, '%m') month"])
            ->where([
                ["ref_key", "eq", "sku"],
                ["ref_value", "in", $skus],
                ["stat_date", "gt", $this->year],
                ["stat_date", "lt", ($this->year + 1).""],
            ])
            ->group("stat_month, ref_value")
            ->order("ref_value, stat_month")
            ->select()->toArray();
        if(empty($yearData)) $this->error("暂无数据");
        $start = 1;
        $currYear = date('Y');
        $months = 12;
        $report = [];
        foreach($skus as $sku) $report[$sku] = [];
        $func = function($currSku, $start, $year, $currStatMonth) use($currYear)
        {
            $tempData = [];
            $currMonth = date('m');
            for($i = $start; $i < $currStatMonth; $i++)
            {
                $tempQty = $currYear == $year && $currMonth < $i ? null : 0;
                $tempStatMonth = $i < 10 ? "0$i" : $i;
                $tempData[] = [
                    'total_qty' => $tempQty,
                    'total_price' => $tempQty,
                    'sku' => $currSku,
                    'stat_date' => "$year-$tempStatMonth",
                    'stat_month' => $tempStatMonth,
                ];
            }
            return $tempData;
        };
        foreach($yearData as $k => $item)
        {
            $currStatMonth = intval(date('m', strtotime($item['stat_month'])));
            $currSku = $item['ref_value'];
            $nextSku = isset($yearData[$k + 1]) ? $yearData[$k + 1]['ref_value'] : '';
            $currVal = & $report[$currSku];
            // 处理左边
            if($start < $currStatMonth)
            {
                $currVal = array_merge($currVal, $func($currSku, $start, date('Y', strtotime($item['stat_month'])), $currStatMonth));
                $start = $currStatMonth;
            }
            // 处理当前
            if($item['stat_month'] < 10) $item['stat_month'] = "0{$item['stat_month']}";
            $item['sku'] = $item['ref_value'];
            $currVal[] = $item;
            $start++;
            // 处理右边
            if($currSku != $nextSku)
            {
                if($start <= $months) $currVal = array_merge($currVal, $func($currSku, $start, $this->year, $months + 1));
                $start = 1;
            }
        }

        // 检查是否有空数据
        foreach($skus as $currSku)
        {
            $currVal = & $report[$currSku];
            if(!empty($currVal)) continue;
            $currVal = array_merge($currVal, $func($currSku, 1, $this->year, $months + 1));
        }
        $data = ['legend' => []];
        foreach(range(1, 12) as $v) $data['xAxis'][] = "{$v}月";
        $index = 0;
        foreach($report as $sku => $item)
        {
            if(!in_array($sku, $data['legend'])) $data['legend'][] = "{$sku} 销量";
            $data['series'][$index]['type'] = 'line';
            $data['series'][$index]['smooth'] = true;
            $data['series'][$index]['stack'] = '总量';
            $data['series'][$index]['name'] = "{$sku} 销量";
            foreach($item as $value)
            {
                $totalPirce = $value['total_price'] !== null ? number_format($value['total_price'], 4, '.', ',') : null;
                $data['series'][$index]['data'][] = ['value'=>$value['total_qty'], 'total_price' => $totalPirce, 'sku' => $sku];
            }
            $index++;
        }
        $this->success('', '', ['title'=>"{$this->year}年销量走势图", 'data' => $data]);
    }

    /**
     * 销量月走势图
     * @date 2021/08/05
     * @author longli
     */
    private function orderMonth()
    {
        $skus = $this->getSkus();
        if(empty($skus)) $this->error("暂无数据");
        $currStatMonth = "{$this->year}-{$this->month}";
        $addMonth = $this->month + 1;
        $monthData = ReportOrderDay::field(["qty total_qty", "total_price", " ref_value", "stat_date", "DATE_FORMAT(stat_date, '%d') stat_day"])
            ->where([
                ["ref_key", "eq", "sku"],
                ["ref_value", "in", $skus],
                ["stat_date", "gt", $currStatMonth],
                ["stat_date", "lt", "{$this->year}-" . ($addMonth > 9 ? $addMonth : "0{$addMonth}")],
            ])
            ->order("ref_value, stat_day")
            ->select()
            ->toArray();
        if(empty($monthData)) $this->error("暂无数据");
        $start = 1;
        $days = date('t', strtotime($currStatMonth));
        $today = date('j');
        $isLastMonth = $currStatMonth == date('Y-m');
        // 初始化数据
        $report = [];
        foreach($skus as $sku) $report[$sku] = [];
        $func = function($currSku, $start, $days) use($currStatMonth, $today, $isLastMonth)
        {
            $tempData = [];
            for($i = $start; $i < $days; $i++)
            {
                $tempQty = $isLastMonth && $today < $i ? null : 0;
                $tempStatDay = $i < 10 ? "0$i" : $i;
                $tempData[] = [
                    'total_qty' => $tempQty,
                    'total_price' => $tempQty,
                    'ref_value' => $currSku,
                    'stat_date' => "$currStatMonth-$tempStatDay",
                    'stat_day' => $tempStatDay,
                ];
            }
            return $tempData;
        };

        foreach($monthData as $k => $item)
        {
            $currStatDay = intval($item['stat_day']);
            $currSku = $item['ref_value'];
            $nextSku = isset($monthData[$k + 1]) ? $monthData[$k + 1]['ref_value'] : '';
            $currVal = & $report[$currSku];
            // 处理左边
            if($start < $currStatDay)
            {
                $currVal = array_merge($currVal, $func($currSku, $start, $currStatDay));
                $start = $currStatDay + 1;
            }
            // 处理当前
            if($item['stat_day'] < 10) $item['stat_day'] = "0{$item['stat_day']}";
            $item['sku'] = $item['ref_value'];
            $currVal[] = $item;
            $start++;
            // 处理右边
            if($currSku != $nextSku)
            {
                if($start <= $days) $currVal = array_merge($currVal, $func($currSku, $start, $days + 1));
                $start = 1;
            }
        }
        // 检查是否有空数据
        foreach($skus as $currSku)
        {
            $currVal = & $report[$currSku];
            if(!empty($currVal)) continue;
            $currVal = array_merge($currVal, $func($currSku, 1, $days + 1));
        }
        $data = ['legend' => []];
        foreach(range(1, $days) as $v) $data['xAxis'][] = "{$v}号";
        $index = 0;
        foreach($report as $sku => $item)
        {
            if(!in_array($sku, $data['legend'])) $data['legend'][] = "{$sku} 销量";
            $data['series'][$index]['type'] = 'line';
            $data['series'][$index]['smooth'] = true;
            $data['series'][$index]['stack'] = '总量';
            $data['series'][$index]['name'] = "{$sku} 销量";
            foreach($item as $value)
            {
                $totalPirce = $value['total_price'] !== null ? number_format($value['total_price'], 4, '.', ',') : null;
                $data['series'][$index]['data'][] = ['value'=>$value['total_qty'], 'total_price' => $totalPirce, 'sku' => $sku];
            }
            $index++;
        }
        $this->success('', '', ['title'=>"{$currStatMonth}月销量走势图", 'data' => $data]);
    }

    /**
     * 获取 sku
     * @date 2021/08/05
     * @author longli
     */
    private function getSkus()
    {
        $s = $this->request->request('sku', '', 'trim');
        if(empty($s))
        {
            $tempSku = ReportOrderDay::field(["max(total_price)", "ref_value"])
                ->where("ref_key", "sku")->value("ref_value");
            $s = ProductStore::field(["product_id"])
                ->with(['product'=>function($query){$query->field(['product_id', 'spu']);}])
                ->where("sku", $tempSku)
                ->find();
            if(!empty($s)) $s = $s->product->spu;
        }
        $sku = \app\common\model\Product::getSkusBySpu($s);
        if(!empty($sku)) return $sku;
        return \app\common\model\ProductStore::field(["sku"])->whereIn("sku", replaceStr($s))->column("sku");
    }
}